home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / IDEINST / ROOTSECT.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  9.8 KB  |  298 lines

  1. ; rootsect.s
  2.  
  3. ;------------------------------------------------------------------------
  4. ;                                    :
  5. ; Hard Disk Root Sector                            :
  6. ; Initiates boot from a hard disk partition, contains hard disk     :
  7. ; read-sector subroutine for use by partition's    boot code.        :
  8. ;                                    :
  9. ; Copyright 1986, 1987, 1988, 1989, 1990 Atari Corp.            :
  10. ; All Rights Reserved                            :
  11. ;                                    :
  12. ; Jul-24-1989    ml.    Modified this for TT.                :
  13. ;            New ROMs will pass the following to this    :
  14. ;            root sector:                    :
  15. ;            d3.l = $444d4172 ("DMAr") to indicate the XBIOS    :
  16. ;                call for DMAread exists.        :
  17. ;            d4.w = boot unit # (iff d3.l = "DMAr")        :
  18. ;            d5.w = user-preference (ignore for now!!)    :
  19. ;            d7.b = ACSI device # in upper 3 bits        :
  20. ;                (should ignore d7.b if d4.w is valid)    :
  21. ; Feb-05-1990    ml.    Modified to reflect the latest boot spec. which    :
  22. ;            includes booting UNIX on the TT.        :
  23. ;            Removed code that handles MSDOS root sector.    :
  24. ;            Handled user-preference as stated in latest    :
  25. ;            TT boot spec.                    :
  26. ; Feb-14-1990    ml.    If a user-preference is passed in through d5     :
  27. ;            but no entry matches it, just quit.  Maybe the    :
  28. ;            preference is for another kind of device.    :
  29. ; Jul-25-1990    ml.    Modified handling of user-preference code, so    :
  30. ;            that bits 1 & 2 of byte 0 of a partition entry    :
  31. ;            do not participate in the comparison.  (This     :
  32. ;            lifts the assumption that they have to be 0.)    :
  33. ;                                    :
  34. ;------------------------------------------------------------------------
  35.  
  36.  
  37. ;---- Hardware registers:
  38. diskctl        equ    $ffff8604    ; (W) disk controller data access
  39. fifo        equ    $ffff8606    ; (W) DMA mode control
  40. dmahigh        equ    $ffff8609    ; (B) DMA base high
  41. dmamid        equ    $ffff860b    ; (B) DMA base medium
  42. dmalow        equ    $ffff860d    ; (B) DMA base low
  43. gpip        equ    $fffffa01    ; (B) bit 5 is DMA interrupt line
  44.  
  45. ;---- OS locations:
  46. flock        equ    $43e        ; (W) DMA chip lock variable
  47. _bootdev    equ    $446        ; (W) boot device number
  48. _hz_200        equ    $4ba        ; (L) 200 hz timer tick
  49. _drvbits    equ    $4c2        ; (L) logical drive map
  50. _dskbufp    equ    $4c6        ; (L) -> 1K disk buffer
  51. _sysbase    equ    $4f2        ; (L) -> OS header
  52.  
  53. ;--- Magic numbers:
  54. bootmagic    equ    $1234        ; executable boot sector checksum
  55. DMAr        equ    $444d4172    ; DMAread() 
  56.  
  57.  
  58. ;+
  59. ;  Root Sector
  60. ;
  61. ;  First branch (+0) goes to partition booter;
  62. ;  Second branch (+2) goes to disk read routine.
  63. ;  Bfat (+6) is a flag for size of FAT entries
  64. ;
  65. ;-
  66. _rootstart::
  67. base:    bra.s    rootboot    ; boot some partition
  68.     bra    dmaread        ; read sectors
  69.  
  70.  
  71. ;+
  72. ;  rootboot - locate a bootable partition and boot from it
  73. ;
  74. ;    - If the [ALT] key is down, just exit;
  75. ;    - Search for bootable partition in sector image;
  76. ;    - If none, just return;
  77. ;    - Otherwise, load partition's boot sector into upper half
  78. ;      of the 1K buffer, checksum it, and execute it if it
  79. ;      checks out;
  80. ;    - Adjust D7 on return so the DMA bus will not lock up.
  81. ;
  82. ;-
  83. rootboot:            ; if this code fails, there's no C:
  84.     bclr.b    #2,_drvbits+3    ; so, clobber 'C' bit in _drvbits
  85.     move.w    #0,_bootdev    ; initialise bootdev to be A:
  86.     movem.l    d3/d5,-(sp)    ; save d3 and d5
  87.     move.w    #-1,-(sp)    ; get state of the shift keys
  88.     move.w    #$0b,-(sp)    ; d0 = Kbshift()
  89.     trap    #13
  90.     addq.w    #4,sp        ; clean-up stack
  91.     btst    #3,d0        ; is [ALT] down?
  92.     bne.s    rb_r        ; (yes, just return)
  93.  
  94.     moveq    #3,d0        ; d0 = partition count
  95.     moveq    #$00f8,d1    ; d1 = mask for boot value
  96.     lea    base+$1c6(pc),a0 ; a0 -> first partition entry
  97.     cmpi.l    #DMAr,d3    ; does DMAread() exist?
  98.     beq.s    rb_0        ; if it does, d4 = physical unit number
  99.     moveq    #-1,d4        ; else d4 = -1 => no DMAread in ROM
  100.     moveq    #$80,d2        ; d2 = old boot value
  101.     bra.s    rb_1        ; and boot the old way
  102.  
  103. rb_0:    move.b    d5,d2        ; else, is there a user preference?
  104.     beq.s    rb_5        ; if not, boot the first bootable partition
  105. rb_1:    btst.b    #0,(a0)        ; does partition exist?
  106.     beq.s    rb_2        ; if not, try next partition slot
  107.     and.b    d1,(a0)        ; mask off irrelevant bits
  108.     cmp.b    (a0),d2        ; p_flg matches boot value?
  109.     beq.s    rb_3        ; (yes --- boot the partition)
  110. rb_2:    adda.w    #12,a0        ; bump to next partition entry
  111.     dbra    d0,rb_1        ; (no --- look for other partitions)
  112.     bra.s    rb_r        ; boot value search fails, return to ROMs
  113.                 ; boot the first bootable partition
  114. rb_5:    btst.b    #0,(a0)        ; does partition exist?
  115.     beq.s    rb_6        ; if not, try next partition slot
  116.     and.b    d1,(a0)        ; partition has a non-zero boot value?
  117.     bne.s    rb_3        ; (yes --- boot the partition)
  118. rb_6:    adda.w    #12,a0        ; (no --- bump to next partition entry)
  119.     dbra    d0,rb_5        ; look for other partitions
  120.                 ; if none is bootable, return to ROMs
  121.  
  122. ;+
  123. ;  Return to BIOS boot routine:
  124. ;    - hack D7 so BIOS never does any more reads
  125. ;      (so the DMA bus will not lock up).
  126. ;
  127. ;  Modified 18-Feb-1988 by AKP to hack D7 (and stop looking on the DMA bus)
  128. ;  ONLY on 11/20-derived ROMs.  Newer ROMs have this bug fixed.
  129. ;-
  130. rb_r:    addq.w    #$08,sp        ; clean up stack
  131. rb_bs:    move.l    _sysbase,a0    ; get the system header address
  132.     move.l    $18(a0),d0    ; d0.l = MMDDYYYY of ROM date
  133.     swap    d0        ; d0.l = YYYYMMDD of ROM date
  134.     cmp.l    #$19870422,d0    ; does this version of ROM need bootstop?
  135.     bcc.s    dontstop    ; nope, if OS is built on or after 4/22/87
  136.     move.w    #$100-$20,d7    ; prevent any other boot sector loads
  137. dontstop:
  138.     rts            ; no bootable partitions
  139.  
  140.  
  141. ;+
  142. ;  Handle bootable partition:
  143. ;    - read its boot sector;
  144. ;    - checksum it;
  145. ;    - if it is executable, call it.
  146. ;-
  147. rb_3:    move.l    4(a0),d6    ; d6 = sector number
  148.     moveq    #1,d5        ; d5 = sector count = 1
  149.     lea    base+$200(pc),a4 ; a4 -> upper half of 1K buffer
  150.     bsr.s    dmaread        ; read partition's boot sector
  151.     tst.w    d0        ; successful?
  152.     bne.s    rb_r        ; (punt on failure)
  153.  
  154.     move.l    a4,a0        ; a0 -> buffer to checksum
  155.     move.w    #$0ff,d1    ; checksum $100 words
  156.     moveq    #0,d0        ; initialise checksum = 0
  157. rb_4:    add.w    (a0)+,d0    ; add (next) word
  158.     dbra    d1,rb_4        ; (loop for every word)
  159.     cmp.w    #bootmagic,d0    ; is the sector executable?
  160.     bne.s    rb_r        ; (no --- return to OS)
  161.     lea    dmaread(pc),a3    ; a3 -> disk read routine
  162.     lea    rb_bs(pc),a5    ; a5 -> bootstop code
  163.     movem.l    (sp)+,d3/d5    ; restore d3 and d5
  164.     jmp    (a4)        ; yes --- jump there
  165.  
  166.  
  167. ;+
  168. ;  dmaread - read sectors from hard disk
  169. ;    Passed:    d4.w = physical unit number (if DMAread() is in ROM)
  170. ;            or -1 (if DMAread() is not in ROM)
  171. ;        d5.w = sector count
  172. ;        d6.l = sector number
  173. ;        d7.b = ddd00000 ('ddd' is the ACSI device number, 0..7)
  174. ;        a4.l -> buffer address
  175. ;
  176. ;    Returns:    EQ: success
  177. ;        NE: read failed;
  178. ;
  179. ;    Uses:    a5-a6/d0-d1 for dmaread here
  180. ;        a0-a2/d0-d2 for DMAread in ROM
  181. ;-
  182. dmaread:
  183.     tst.w    d4        ; DMAread exists in ROM?
  184.     bmi.s    dmr_0        ; if not, use dmaread() in this root sector
  185.     move.w    d4,-(sp)    ; pdev
  186.     move.l    a4,-(sp)    ; buf
  187.     move.w    d5,-(sp)    ; count
  188.     move.l    d6,-(sp)    ; sectnum
  189.     move.w    #$2a,-(sp)    ; DMAread(sectnum, count, buf, pdev)
  190.     trap    #14
  191.     adda.w    #$0e,sp        ; clean up stack
  192.     bra    ww_w        ; done
  193.  
  194. dmr_0:    st    flock        ; lock DMA chip (against vblank)
  195.     move.l    _hz_200,d0    ; delay for 1/200th..1/100th of a second
  196.     addq.l    #2,d0        ; d0 = target time
  197. dmr_dl:    cmp.l    _hz_200,d0    ; target time passed?
  198.     bcc.s    dmr_dl        ; (not yet)
  199.  
  200.     move.w    #dmahigh,a6    ; a6 -> base of DMA address registers
  201.     movem.l    d6/a4,-(sp)    ; stuff sect# & addr onto stack for access
  202.     move.b    7(sp),4(a6)    ; load dmalow,    (do not change the order)
  203.     move.b    6(sp),2(a6)    ;      dmamid,  (of loading these.)
  204.     move.b    5(sp),(a6)    ;  and dmahigh.
  205.  
  206.     lea    dmr_st(pc),a6    ; a6 -> command frame table
  207.     move.b    1(sp),1(a6)    ; write high,
  208.     move.b    2(sp),5(a6)    ;    mid,
  209.     move.b    3(sp),9(a6)    ;    and low sector bytes in table
  210.     move.b    d5,$d(a6)    ; write sector count in table
  211.     addq.w    #$8,sp        ; (cleanup stack)
  212.  
  213.     move.w    #fifo,a6    ; a6 -> DMA control register
  214.     move.w    #diskctl,a5    ; a5 -> DMA data register
  215.  
  216.     move.w    #$198,(a6)    ; toggle R/W, leave in Read state
  217.     move.w    #$098,(a6)
  218.     move.w    d5,(a5)        ; write sector count register
  219.  
  220.     move.w    #$088,(a6)    ; select dma bus (not SCR)
  221.  
  222.     moveq    #0,d0        ; clear d0
  223.     move.b    d7,d0        ; setup d0.L with devno+command
  224.     or.b    #$08,d0        ; d0.b = devno<<5 .OR. "READ" command bits
  225.     swap    d0
  226.     move.w    #$08a,d0
  227.     bsr.s    wcbyte        ; d0.L = xxxxxxxxDDD01000xxxxxxx010001010
  228.  
  229.     lea    dmr_st(pc),a0    ; a0 -> bytestream for commands
  230.     moveq    #3,d2
  231. dmr_1:    move.l    (a0)+,d0    ; get next command byte
  232.     bsr.s    wcbyte        ; write it
  233.     dbra    d2,dmr_1
  234.  
  235.     move.l    #$0000000a,(a5)    ; write byte 5 (controlByte = $00)
  236.     move.l    #400,d1        ; timeout = 2.0 sec
  237.     bsr.s    wwait        ; wait for completion
  238.  
  239.     move.w    #$08a,(a6)    ; select status reg
  240.     move.w    (a5),d0        ; get return code from DMA device
  241.     and.w    #$00ff,d0    ; strip crufty bits
  242.     beq.s    dmr_r        ; (return if OK)
  243.  
  244. ;--- reset DMA, return status
  245. dmr_q:    moveq    #-1,d0        ; return -1 (error)
  246. dmr_r:    move.w    #$080,(a6)    ; cleanup DMA chip for floppy driver
  247.     sf    flock        ; unlock DMA chip
  248. ww_w:    rts            ; return
  249.  
  250.  
  251. ;--- bytes in the command packet:
  252. dmr_st:        dc.l    $0000008a    ; byte 1 (devno = 0, blockno = 0)
  253.         dc.l    $0000008a    ; byte 2 (blockno = 0)
  254.         dc.l    $0000008a    ; byte 3 (blockno = 0)
  255.         dc.l    $0001008a    ; byte 4 (count = 1)
  256.  
  257.  
  258. ;+
  259. ;  wcbyte - write ACSI command byte, wait for IRQ
  260. ;    Passed:    D0.L = command byte and FIFO control
  261. ;            bits 16..23 = command byte,
  262. ;            bits 0..7 = FIFO control bits
  263. ;        a5 -> $ff8604
  264. ;
  265. ;    Returns:    NE on failure (timeout) to the CALLER'S CALLER
  266. ;        EQ on successful ACK
  267. ;
  268. ;    Uses:    d1
  269. ;
  270. ;-
  271. wcbyte:    move.l    d0,(a5)        ; write WDC, WDL [due to jwt]
  272.     moveq    #10,d1        ; wait 1/20th second
  273. wwait:    add.l    _hz_200,d1    ; d1 = time to quit at...
  274. ww_1:    btst.b    #5,gpip        ; disk done?
  275.     beq.s    ww_w        ; (yes, return)
  276.     cmp.l    _hz_200,d1    ; timeout?
  277.     bcc.s    ww_1        ; (not yet -- wait some more...)
  278.     addq.w    #4,sp        ; pop the return address
  279.     bra.s    dmr_q        ; handle error
  280.  
  281. _rootend::
  282.  
  283.     bss
  284. ;+
  285. ;  Hard disk partition information
  286. ;
  287. ;-
  288. format_info:    ds.b    12    ; formatting information
  289. hd_size:    ds.l    1    ; hd_siz
  290. part0:        ds.b    12    ; partition 0
  291. part1:        ds.b    12    ; partition 1
  292. part2:        ds.b    12    ; partition 2
  293. part3:        ds.b    12    ; partition 3
  294. bsl_st:        ds.l    1    ; bad sector list start
  295. bsl_cnt:    ds.l    1    ; bad sector list count
  296. checksum:    ds.w    1    ; (reserved for sector chksum)
  297.  
  298.